home *** CD-ROM | disk | FTP | other *** search
- Path: news.larc.nasa.gov!amiga-request
- From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
- Subject: v91i124: bmake 0.6 - automate recompiling multiple source files, Part02/03
- Reply-To: ENG BENNY <engb@ecf.toronto.edu>
- Newsgroups: comp.sources.amiga
- Message-ID: <comp.sources.amiga.v91i124@ab20.larc.nasa.gov>
- References: <comp.sources.amiga.v91i123@ab20.larc.nasa.gov>
- Date: 04 Jul 91 16:38:43 GMT
- Approved: tadguy@uunet.UU.NET (Tad Guy)
- X-Mail-Submissions-To: amiga@uunet.uu.net
- X-Post-Discussions-To: comp.sys.amiga.misc
-
- Submitted-by: ENG BENNY <engb@ecf.toronto.edu>
- Posting-number: Volume 91, Issue 124
- Archive-name: utilities/bmake-0.6/part02
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 3)."
- # Contents: copying expand.c fncall.c input.c make.c read.c
- # Wrapped by tadguy@ab20 on Thu Jul 4 12:38:41 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'copying' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'copying'\"
- else
- echo shar: Extracting \"'copying'\" \(12488 characters\)
- sed "s/^X//" >'copying' <<'END_OF_FILE'
- X
- X GNU GENERAL PUBLIC LICENSE
- X Version 1, February 1989
- X
- X Copyright (C) 1989 Free Software Foundation, Inc.
- X 675 Mass Ave, Cambridge, MA 02139, USA
- X Everyone is permitted to copy and distribute verbatim copies
- X of this license document, but changing it is not allowed.
- X
- X Preamble
- X
- X The license agreements of most software companies try to keep users
- Xat the mercy of those companies. By contrast, our General Public
- XLicense is intended to guarantee your freedom to share and change free
- Xsoftware--to make sure the software is free for all its users. The
- XGeneral Public License applies to the Free Software Foundation's
- Xsoftware and to any other program whose authors commit to using it.
- XYou can use it for your programs, too.
- X
- X When we speak of free software, we are referring to freedom, not
- Xprice. Specifically, the General Public License is designed to make
- Xsure that you have the freedom to give away or sell copies of free
- Xsoftware, that you receive source code or can get it if you want it,
- Xthat you can change the software or use pieces of it in new free
- Xprograms; and that you know you can do these things.
- X
- X To protect your rights, we need to make restrictions that forbid
- Xanyone to deny you these rights or to ask you to surrender the rights.
- XThese restrictions translate to certain responsibilities for you if you
- Xdistribute copies of the software, or if you modify it.
- X
- X For example, if you distribute copies of a such a program, whether
- Xgratis or for a fee, you must give the recipients all the rights that
- Xyou have. You must make sure that they, too, receive or can get the
- Xsource code. And you must tell them their rights.
- X
- X We protect your rights with two steps: (1) copyright the software, and
- X(2) offer you this license which gives you legal permission to copy,
- Xdistribute and/or modify the software.
- X
- X Also, for each author's protection and ours, we want to make certain
- Xthat everyone understands that there is no warranty for this free
- Xsoftware. If the software is modified by someone else and passed on, we
- Xwant its recipients to know that what they have is not the original, so
- Xthat any problems introduced by others will not reflect on the original
- Xauthors' reputations.
- X
- X The precise terms and conditions for copying, distribution and
- Xmodification follow.
- X
- X GNU GENERAL PUBLIC LICENSE
- X TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- X
- X 0. This License Agreement applies to any program or other work which
- Xcontains a notice placed by the copyright holder saying it may be
- Xdistributed under the terms of this General Public License. The
- X"Program", below, refers to any such program or work, and a "work based
- Xon the Program" means either the Program or any work containing the
- XProgram or a portion of it, either verbatim or with modifications. Each
- Xlicensee is addressed as "you".
- X
- X 1. You may copy and distribute verbatim copies of the Program's source
- Xcode as you receive it, in any medium, provided that you conspicuously and
- Xappropriately publish on each copy an appropriate copyright notice and
- Xdisclaimer of warranty; keep intact all the notices that refer to this
- XGeneral Public License and to the absence of any warranty; and give any
- Xother recipients of the Program a copy of this General Public License
- Xalong with the Program. You may charge a fee for the physical act of
- Xtransferring a copy.
- X
- X 2. You may modify your copy or copies of the Program or any portion of
- Xit, and copy and distribute such modifications under the terms of Paragraph
- X1 above, provided that you also do the following:
- X
- X a) cause the modified files to carry prominent notices stating that
- X you changed the files and the date of any change; and
- X
- X b) cause the whole of any work that you distribute or publish, that
- X in whole or in part contains the Program or any part thereof, either
- X with or without modifications, to be licensed at no charge to all
- X third parties under the terms of this General Public License (except
- X that you may choose to grant warranty protection to some or all
- X third parties, at your option).
- X
- X c) If the modified program normally reads commands interactively when
- X run, you must cause it, when started running for such interactive use
- X in the simplest and most usual way, to print or display an
- X announcement including an appropriate copyright notice and a notice
- X that there is no warranty (or else, saying that you provide a
- X warranty) and that users may redistribute the program under these
- X conditions, and telling the user how to view a copy of this General
- X Public License.
- X
- X d) You may charge a fee for the physical act of transferring a
- X copy, and you may at your option offer warranty protection in
- X exchange for a fee.
- X
- XMere aggregation of another independent work with the Program (or its
- Xderivative) on a volume of a storage or distribution medium does not bring
- Xthe other work under the scope of these terms.
- X
- X 3. You may copy and distribute the Program (or a portion or derivative of
- Xit, under Paragraph 2) in object code or executable form under the terms of
- XParagraphs 1 and 2 above provided that you also do one of the following:
- X
- X a) accompany it with the complete corresponding machine-readable
- X source code, which must be distributed under the terms of
- X Paragraphs 1 and 2 above; or,
- X
- X b) accompany it with a written offer, valid for at least three
- X years, to give any third party free (except for a nominal charge
- X for the cost of distribution) a complete machine-readable copy of the
- X corresponding source code, to be distributed under the terms of
- X Paragraphs 1 and 2 above; or,
- X
- X c) accompany it with the information you received as to where the
- X corresponding source code may be obtained. (This alternative is
- X allowed only for noncommercial distribution and only if you
- X received the program in object code or executable form alone.)
- X
- XSource code for a work means the preferred form of the work for making
- Xmodifications to it. For an executable file, complete source code means
- Xall the source code for all modules it contains; but, as a special
- Xexception, it need not include source code for modules which are standard
- Xlibraries that accompany the operating system on which the executable
- Xfile runs, or for standard header files or definitions files that
- Xaccompany that operating system.
- X
- X 4. You may not copy, modify, sublicense, distribute or transfer the
- XProgram except as expressly provided under this General Public License.
- XAny attempt otherwise to copy, modify, sublicense, distribute or transfer
- Xthe Program is void, and will automatically terminate your rights to use
- Xthe Program under this License. However, parties who have received
- Xcopies, or rights to use copies, from you under this General Public
- XLicense will not have their licenses terminated so long as such parties
- Xremain in full compliance.
- X
- X 5. By copying, distributing or modifying the Program (or any work based
- Xon the Program) you indicate your acceptance of this license to do so,
- Xand all its terms and conditions.
- X
- X 6. Each time you redistribute the Program (or any work based on the
- XProgram), the recipient automatically receives a license from the original
- Xlicensor to copy, distribute or modify the Program subject to these
- Xterms and conditions. You may not impose any further restrictions on the
- Xrecipients' exercise of the rights granted herein.
- X
- X 7. The Free Software Foundation may publish revised and/or new versions
- Xof the General Public License from time to time. Such new versions will
- Xbe similar in spirit to the present version, but may differ in detail to
- Xaddress new problems or concerns.
- X
- XEach version is given a distinguishing version number. If the Program
- Xspecifies a version number of the license which applies to it and "any
- Xlater version", you have the option of following the terms and conditions
- Xeither of that version or of any later version published by the Free
- XSoftware Foundation. If the Program does not specify a version number of
- Xthe license, you may choose any version ever published by the Free Software
- XFoundation.
- X
- X 8. If you wish to incorporate parts of the Program into other free
- Xprograms whose distribution conditions are different, write to the author
- Xto ask for permission. For software which is copyrighted by the Free
- XSoftware Foundation, write to the Free Software Foundation; we sometimes
- Xmake exceptions for this. Our decision will be guided by the two goals
- Xof preserving the free status of all derivatives of our free software and
- Xof promoting the sharing and reuse of software generally.
- X
- X NO WARRANTY
- X
- X 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
- XFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
- XOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
- XPROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
- XOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- XMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
- XTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
- XPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
- XREPAIR OR CORRECTION.
- X
- X 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
- XWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
- XREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
- XINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
- XOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
- XTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
- XYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
- XPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
- XPOSSIBILITY OF SUCH DAMAGES.
- X
- X END OF TERMS AND CONDITIONS
- X
- X Appendix: How to Apply These Terms to Your New Programs
- X
- X If you develop a new program, and you want it to be of the greatest
- Xpossible use to humanity, the best way to achieve this is to make it
- Xfree software which everyone can redistribute and change under these
- Xterms.
- X
- X To do so, attach the following notices to the program. It is safest to
- Xattach them to the start of each source file to most effectively convey
- Xthe exclusion of warranty; and each file should have at least the
- X"copyright" line and a pointer to where the full notice is found.
- X
- X <one line to give the program's name and a brief idea of what it does.>
- X Copyright (C) 19yy <name of author>
- X
- X This program is free software; you can redistribute it and/or modify
- X it under the terms of the GNU General Public License as published by
- X the Free Software Foundation; either version 1, or (at your option)
- X any later version.
- X
- X This program is distributed in the hope that it will be useful,
- X but WITHOUT ANY WARRANTY; without even the implied warranty of
- X MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X GNU General Public License for more details.
- X
- X You should have received a copy of the GNU General Public License
- X along with this program; if not, write to the Free Software
- X Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- XAlso add information on how to contact you by electronic and paper mail.
- X
- XIf the program is interactive, make it output a short notice like this
- Xwhen it starts in an interactive mode:
- X
- X Gnomovision version 69, Copyright (C) 19xx name of author
- X Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- X This is free software, and you are welcome to redistribute it
- X under certain conditions; type `show c' for details.
- X
- XThe hypothetical commands `show w' and `show c' should show the
- Xappropriate parts of the General Public License. Of course, the
- Xcommands you use may be called something other than `show w' and `show
- Xc'; they could even be mouse-clicks or menu items--whatever suits your
- Xprogram.
- X
- XYou should also get your employer (if you work as a programmer) or your
- Xschool, if any, to sign a "copyright disclaimer" for the program, if
- Xnecessary. Here a sample; alter the names:
- X
- X Yoyodyne, Inc., hereby disclaims all copyright interest in the
- X program `Gnomovision' (a program to direct compilers to make passes
- X at assemblers) written by James Hacker.
- X
- X <signature of Ty Coon>, 1 April 1989
- X Ty Coon, President of Vice
- X
- XThat's all there is to it!
- END_OF_FILE
- if test 12488 -ne `wc -c <'copying'`; then
- echo shar: \"'copying'\" unpacked with wrong size!
- fi
- # end of 'copying'
- fi
- if test -f 'expand.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'expand.c'\"
- else
- echo shar: Extracting \"'expand.c'\" \(6120 characters\)
- sed "s/^X//" >'expand.c' <<'END_OF_FILE'
- X/* expand.c
- X * (c) Copyright 1991 by Ben Eng, All Rights Reserved
- X *
- X * macro expansion
- X */
- X
- X#include <clib/exec_protos.h>
- X
- X#include <ctype.h>
- X
- X#include "make.h"
- X#include "depend.h"
- X
- Xstatic int expand_macros2( char *dest, char *src, int maxlen );
- Xstatic int expand_macros3( char *src, int maxlen );
- X
- X/* define the criterion for detecting infinitely recursive
- X * macro expansions
- X */
- Xstatic int expand_level = 0;
- X#define MAX_RECURSION 32
- X#define MAX_ITERATION 256
- X
- X/* returns 0 if a function was completed successfully
- X */
- Xstatic struct macro *
- Xexpand_fncall( char *src, int maxlen )
- X{
- X static struct macro *fnmac = NULL;
- X struct fncall *fc;
- X char fn[ 40 ], *next = src;
- X int addlen;
- X
- X if( fnmac) {
- X if( fnmac->expansion ) {
- X free( fnmac->expansion );
- X fnmac->expansion = NULL;
- X }
- X }
- X else if( fnmac = new_macro( NULL, NULL ))
- X fnmac->flags |= MF_SIMPLE;
- X else return( NULL );
- X
- X next = parse_str( fn, next, sizeof(fn));
- X if( fc = find_fncall( fn )) {
- X if( (*fc->call)( fnmac, next )) {
- X logprintf( "function call %s returned ERROR\n", fc->name );
- X return( NULL );
- X }
- X fnmac->flags |= MF_SIMPLE;
- X return( fnmac );
- X }
- X return( NULL );
- X}
- X
- X/* expand a macro reference with only a single $(x) instance
- X * handles recursive expansion
- X */
- Xstatic int
- Xexpand_macros3( char *src, int maxlen )
- X{
- X char *dest = NULL;
- X char *macroname = NULL;
- X char *dollar;
- X
- X dollar = strchr( src, '$' );
- X if( dollar ) {
- X struct macro *mac = NULL;
- X char *out, *next;
- X int outlen = 0;
- X char delimchar = (char)0;
- X
- X debugprintf( 6,( "expand_macros3(%s,%d)\n", src, maxlen ));
- X
- X /* could get away with only allocating maxlen to save memory */
- X macroname = (char *)malloc( Param.MaxLine );
- X dest = (char *)calloc( Param.MaxLine, 1 );
- X if( !macroname || !dest ) goto death;
- X
- X out = dest;
- X
- X memset( macroname, 0, Param.MaxLine);
- X for( next = src; next < dollar && outlen < maxlen; outlen++ )
- X *out++ = *next++;
- X
- X next = dollar + 1;
- X if( outlen >= maxlen ) goto death;
- X
- X if( *next == '(' ) delimchar = ')';
- X else if( *next == '{' ) delimchar = '}';
- X
- X if( delimchar ) { /* multi letter variable name */
- X char *n;
- X int i = 0;
- X
- X for( n = ++next; *n && i < Param.MaxLine-1; n++ ) {
- X if( *n == delimchar ) break;
- X macroname[ i++ ] = *n;
- X }
- X if( *n != delimchar ) {
- X logprintf( "macro name is too long [%s]\n", macroname );
- X logprintf( "macro names are limited to %d\n",
- X Param.MaxLine );
- X goto death;
- X }
- X next = n + 1;
- X }
- X else { /* single letter variable name */
- X macroname[ 0 ] = *next++; /* advance past the macroname */
- X }
- X
- X if( mac = expand_fncall( macroname, maxlen - outlen )) {
- X debugprintf( 4,( "fncall macro [%s] = %s\n", macroname,
- X mac->expansion ));
- X }
- X else if( !(mac = find_macro( macroname )) && getenv( macroname )) {
- X /* use getenv() to assign a simple macro */
- X debugprintf( 4,( "getenv macro [%s]\n", macroname ));
- X if( mac = set_macro( macroname, getenv( macroname ))) {
- X mac->flags |= MF_SIMPLE;
- X }
- X }
- X if( mac ) {
- X int cdrlen = maxlen - outlen;
- X if( mac->flags & MF_EXPANDED ) {
- X logprintf( "infinitely recursive macro expansion: %s\n",
- X macroname );
- X goto death;
- X }
- X memset( out, 0, cdrlen );
- X if( mac->expansion) strncpy( out, mac->expansion, cdrlen );
- X cdrlen -= strlen( out );
- X if( cdrlen < 0 ) {
- X logprintf( "expand_macros3 ERROR: cdrlen is %d\n",
- X cdrlen );
- X goto death;
- X }
- X strncpy( out + strlen(out), next, cdrlen );
- X if( !(mac->flags & MF_SIMPLE )) {
- X /* recursively expand nested macro expansion */
- X mac->flags |= MF_EXPANDED;
- X if( expand_macros2( out, out, cdrlen )) goto death;
- X mac->flags &= ~MF_EXPANDED;
- X }
- X }
- X else {
- X logprintf( "WARNING: unknown macro [%s]\n", macroname );
- X strncpy( out + strlen(out), next, maxlen - outlen );
- X }
- X /* for next macro occurrence on the line */
- X outlen = min( strlen( dest ), maxlen );
- X
- X debugprintf( 6,( "expand_macros3 returns [%s] %d\n", dest, outlen ));
- X
- X strncpy( src, dest, outlen ); /* copy the expansion back */
- X src[ outlen ] = (char)0;
- X free( macroname ); macroname = NULL;
- X free( dest ); dest = NULL;
- X } /* dollar */
- X
- X return( 0 );
- Xdeath:
- X if( macroname ) free( macroname );
- X if( dest ) free( dest );
- X return( 1 );
- X}
- X
- X/* find the rightmost occurrence of the character tok
- X * starting at prev in the string
- X */
- Xstatic char *
- Xstrrlchr( char *string, char tok, char *prev )
- X{
- X while( prev >= string ) {
- X if( *prev == tok ) return( prev );
- X prev--;
- X }
- X return( NULL );
- X}
- X
- X/* expand a line with multiple $(x) instances
- X * expand right to left to avoid recursion
- X */
- Xstatic int
- Xexpand_macros2( char *dest, char *src, int maxlen )
- X{
- X char *dollar, *prev;
- X int iteration = 0;
- X
- X /* increment the recursion level counter */
- X if( ++expand_level > MAX_RECURSION ){
- X logprintf( "Infinite Macro expansion aborted at %d recursions\n",
- X expand_level );
- X return( 1 );
- X }
- X debugprintf( 6,( "expand_macros2(%s,%d)\n", src, maxlen ));
- X if( src != dest ) strncpy( dest, src, maxlen );
- X prev = dest + strlen(dest);
- X while( dollar = strrlchr( dest, '$', prev )) {
- X if( ++iteration > MAX_ITERATION ) {
- X logprintf( "Infinite Macro expansion aborted at %d iterations\n",
- X iteration );
- X return( 1 );
- X }
- X if( dollar[-1] == '$' || dollar[-1] == '\\' ) {
- X shift_string_left( dollar - 1, 1 );
- X --dollar;
- X }
- X else if( expand_macros3( dollar, maxlen - (int)(dollar - dest) ))
- X return( 1 );
- X prev = dollar - 1;
- X }
- X debugprintf( 6,( "expand_macros2 returns [%s]\n", dest ));
- X return( 0 );
- X}
- X
- X/* to reset each variable's flags before expansion begins */
- Xstatic long
- Xreset_macroflag( struct macro *mac )
- X{
- X mac->flags &= ~MF_EXPANDED;
- X return( 0 );
- X}
- X
- X/* top level macro expansion call
- X * this is the entry point called from the outside
- X */
- Xint
- Xexpand_macros( char *dest, char *src, int maxlen )
- X{
- X expand_level = 0; /* reset the recursion level counter */
- X memset( dest, 0, maxlen );
- X for_list( &Global.macrolist, reset_macroflag );
- X if( expand_macros2( dest, src, maxlen - 1 )) {
- X logprintf( "Error expanding $(%s)\n", src );
- X return( 1 );
- X }
- X
- X debugprintf( 3,( "expand_macros [%s] to [%s]\n", src, dest ));
- X return( 0 );
- X}
- END_OF_FILE
- if test 6120 -ne `wc -c <'expand.c'`; then
- echo shar: \"'expand.c'\" unpacked with wrong size!
- fi
- # end of 'expand.c'
- fi
- if test -f 'fncall.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fncall.c'\"
- else
- echo shar: Extracting \"'fncall.c'\" \(10300 characters\)
- sed "s/^X//" >'fncall.c' <<'END_OF_FILE'
- X/* fncall.c
- X * (c) Copyright 1991 by Ben Eng, All Rights Reserved
- X *
- X */
- X
- X#include <clib/exec_protos.h>
- X
- X#include <ctype.h>
- X#include <scdir.h>
- X
- X#include "make.h"
- X#include "depend.h"
- X
- X#if FNCALLS
- X
- X/* pattern matching routine */
- Xint
- Xismatch( char *pat, char *text )
- X{
- X char *wild;
- X int len;
- X
- X debugprintf( 7, ( "ismatch(%s,%s)\n", pat, text ));
- X
- X wild = find_token( pat, '%' );
- X
- X if( !wild) return( strcmp( pat, text ) ? 0 : 1 );
- X
- X /* the length of the part of pat before the % */
- X len = (int)(wild - pat);
- X
- X if( len && strncmp( pat, text, len )) return( 0 ); /* no match */
- X
- X /* the length of the part of pat after the % */
- X len = (int)(pat + strlen(pat) - wild - 1);
- X if( len && strncmp( wild + 1, text + strlen(text) - len, len ))
- X return( 0 ); /* no match */
- X
- X return( 1 ); /* match */
- X}
- X
- X/* function calls (mac, string)
- X *
- X * The string parameter is the rest of the arguments passed to the
- X * function call. string is modifiable in fncalls because it is
- X * actually contained within the macroname array[] which isn't
- X * really used again after the fncall returns.
- X *
- X * returns 0 if successful, 1 if error
- X * with side effect: mac->expansion = strdup( result_string );
- X *
- X */
- X
- Xstatic char argument_missing[] = "argument missing: %s %s\n";
- Xstatic char error_no_memory[] = "error: no memory\n";
- X
- Xstatic int
- Xfn_basename( struct macro *mac, char *string )
- X{
- X char *filelist = NULL;
- X char *out, *text, *cptr;
- X int len = 0;
- X char word[ MAXPATHNAME ];
- X
- X filelist = (char *)calloc( Param.MaxLine, 1 );
- X if( !filelist ) {
- X logfile( error_no_memory );
- X return( 1 );
- X }
- X
- X out = filelist;
- X text = string;
- X
- X while( len < Param.MaxLine ) {
- X text = parse_str( word, text, sizeof(word));
- X if( !*word ) break; /* no more words in text */
- X if( (cptr = strrchr( word, '.' )) && ( basename(word) <= cptr )) {
- X *cptr = (char)0; /* truncate the word at the `.' */
- X }
- X len += strlen( word );
- X if( len < Param.MaxLine ) {
- X if( out != filelist ) {
- X *out++ = ' ';
- X len++;
- X }
- X strcpy( out, word );
- X out = filelist + len;
- X }
- X } /* while */
- X *out = (char)0;
- X if( len > 0 ) mac->expansion = strdup( filelist );
- X free( filelist );
- X return( 0 );
- X}
- X
- Xstatic int
- Xdo_addfix( struct macro *mac, char *string, int how_fix )
- X{
- X char *filelist = NULL;
- X char *suf, *str = string;
- X
- X filelist = (char *)calloc( Param.MaxLine, 1 );
- X if( !filelist ) {
- X logfile( error_no_memory );
- X return( 1 );
- X }
- X
- X while( isspace( *str )) str++;
- X suf = str;
- X while( *str && *str != ',' && str[-1] != '\\' ) str++;
- X if( *suf != ',' && *str == ',' && str[-1] != '\\' ) {
- X char *out, *text, *cptr;
- X int suflen, len = 0;
- X char word[ MAXPATHNAME ];
- X
- X *str++ = (char)0; /* null terminate the suffix */
- X suflen = strlen( suf );
- X out = filelist;
- X text = str;
- X
- X while( len < Param.MaxLine ) {
- X text = parse_str( word, text, sizeof(word));
- X if( !*word ) break; /* no more words in text */
- X if( (strlen( word )+suflen) < sizeof(word)) {
- X if( how_fix ) /* append the suffix */
- X strcat( word, suf );
- X else { /* prepend the prefix */
- X len += strlen( suf );
- X if( len + 1 < Param.MaxLine ) {
- X if( out != filelist ) {
- X *out++ = ' ';
- X len++;
- X }
- X strcpy( out, suf );
- X out = filelist + len;
- X }
- X }
- X }
- X len += strlen( word );
- X if( len + 1 < Param.MaxLine ) {
- X if( out != filelist & how_fix ) {
- X *out++ = ' ';
- X len++;
- X }
- X strcpy( out, word );
- X out = filelist + len;
- X }
- X } /* while */
- X *out = (char)0;
- X if( len > 0 ) mac->expansion = strdup( filelist );
- X }
- X free( filelist );
- X return( 0 );
- X}
- X
- Xstatic int
- Xfn_addprefix( struct macro *mac, char *string )
- X{
- X return( do_addfix( mac, string, 0 ));
- X}
- X
- Xstatic int
- Xfn_addsuffix( struct macro *mac, char *string )
- X{
- X return( do_addfix( mac, string, 1 ));
- X}
- X
- Xstatic int
- Xdo_filter( struct macro *mac, char *string, int how_filter )
- X{
- X char *str = string;
- X char *pat;
- X int len;
- X
- X while( isspace( *str )) str++;
- X pat = str;
- X while( *str && *str != ',' && str[-1] != '\\' ) str++;
- X if( *pat != ',' && *str == ',' && str[-1] != '\\' ) {
- X char word[ 80 ];
- X char *text, *out;
- X
- X *str++ = (char)0;
- X
- X if( !( mac->expansion = strdup( str )))
- X return( 0 ); /* no mem */
- X out = mac->expansion;
- X
- X for( text = out;; ) {
- X text = parse_str( word, text, sizeof(word));
- X if( !*word ) break; /* no more words in text */
- X
- X if( how_filter ) {
- X if( ismatch( pat, word )) {
- X out = text + 1;
- X }
- X else { /* no match remove it */
- X while( isspace( *text )) text++;
- X shift_string_left( out, (int)(text - out));
- X text = out;
- X }
- X }
- X else {
- X if( ismatch( pat, word )) {
- X while( isspace( *text )) text++;
- X shift_string_left( out, (int)(text - out));
- X text = out;
- X }
- X else { /* no match remove it */
- X out = text + 1;
- X }
- X }
- X } /* for */
- X *out = (char)0;
- X return( 0 );
- X }
- X logprintf( argument_missing, "filter", string );
- X return( 1 );
- X}
- X
- Xstatic int
- Xfn_filter( struct macro *mac, char *string )
- X{
- X return( do_filter( mac, string, 1 ));
- X}
- X
- Xstatic int
- Xfn_filter_out( struct macro *mac, char *string )
- X{
- X return( do_filter( mac, string, 0 ));
- X}
- X
- Xstatic int
- Xfn_findstring( struct macro *mac, char *string )
- X{
- X char *find, *in, *str = string;
- X int len;
- X
- X while( isspace( *str )) str++;
- X find = str;
- X while( *str && *str != ',' && str[-1] != '\\' ) str++;
- X if( *find != ',' && *str == ',' && str[-1] != '\\' ) {
- X *str++ = (char)0;
- X in = str;
- X while( *str ) str++; /* find end string */
- X len = strlen( find );
- X str -= len; /* str marks the end of searching */
- X
- X while( in <= str ) {
- X /* logprintf( "looking for \"%s\" in \"%s\"\n", find, in ); */
- X
- X if( !strncmp( find, in, len )) { /* found */
- X mac->expansion = strdup( find );
- X break;
- X }
- X in++;
- X }
- X }
- X else {
- X logprintf( argument_missing, "findstring", string );
- X return( 1 );
- X }
- X return( 0 );
- X}
- X
- Xstatic int
- Xfn_strip( struct macro *mac, char *str )
- X{
- X while( isspace( *str )) str++;
- X if( *str && (mac->expansion = strdup( str ))) {
- X register char *d = mac->expansion;
- X register char *s = mac->expansion;
- X while( *s ) {
- X *d++ = *s;
- X if( isspace(*s)) while( isspace( *s)) s++;
- X else s++;
- X }
- X if( isspace( *d )) {
- X while( isspace( *d ) && d > mac->expansion ) d--;
- X d++;
- X }
- X *d = (char)0;
- X }
- X return( 0 );
- X}
- X
- Xstatic int
- Xfn_subst( struct macro *mac, char *string )
- X{
- X char *str = string;
- X char *from, *to, *text;
- X int len;
- X
- X while( isspace( *str )) str++;
- X from = str;
- X while( *str && *str != ',' && str[-1] != '\\' ) str++;
- X if( *from != ',' && *str == ',' && str[-1] != '\\' ) {
- X *str++ = (char)0;
- X to = str;
- X while( *str && *str != ',' && str[-1] != '\\' ) str++;
- X if( *to != ',' && *str == ',' && str[-1] != '\\' && str[ 1 ] ) {
- X *str++ = (char)0;
- X text = str;
- X while( *str ) str++; /* find end string */
- X len = strlen( from );
- X
- X if( strlen( to ) != len ) {
- X logprintf( "subst: args not the same size %s,%s\n",
- X from, to );
- X return( 1 );
- X }
- X
- X text = mac->expansion = strdup( text );
- X str = text + strlen( text ) - len; /* end of search */
- X while( text <= str ) {
- X if( !strncmp( from, text, len )) { /* found */
- X strncpy( text, to, len );
- X }
- X text++;
- X }
- X return( 0 );
- X }
- X }
- X logprintf( argument_missing, "subst", string );
- X return( 1 );
- X}
- X
- Xstatic int
- Xfn_wildcard( struct macro *mac, char *string )
- X{
- X char *filelist = NULL;
- X char *pat = string;
- X
- X filelist = (char *)calloc( Param.MaxLine, 1 );
- X if( !filelist ) {
- X logfile( error_no_memory );
- X return( 1 );
- X }
- X while( isspace( *pat )) pat++;
- X if( *pat ) {
- X char *out = filelist;
- X char *fn;
- X int len = 0;
- X
- X while( len < Param.MaxLine ) {
- X if( !(fn = scdir( pat ))) break; /* no more */
- X if( out != filelist ) {
- X *out++ = ' ';
- X len++;
- X }
- X len += strlen( fn );
- X if( len < Param.MaxLine ) {
- X strcpy( out, fn );
- X out = filelist + len;
- X }
- X }
- X if( len > 0 ) mac->expansion = strdup( filelist );
- X scdir_abort();
- X }
- X free( filelist );
- X return( 0 );
- X}
- X
- X
- Xint
- Xdo_word( struct macro *mac, char *string, int word )
- X{
- X char *begin, *end;
- X
- X if( begin = find_word( string, word )) {
- X end = begin;
- X while( *end && !isspace( *end )) end++;
- X *end = (char)0; /* null terminate past the end of word */
- X mac->expansion = strdup( begin );
- X }
- X return( 0 );
- X}
- X
- Xstatic int
- Xfn_firstword( struct macro *mac, char *string )
- X{
- X while( isspace( *string )) string++;
- X return( do_word( mac, string, 1 ));
- X}
- X
- Xstatic int
- Xfn_word( struct macro *mac, char *string )
- X{
- X char *comma;
- X int word;
- X
- X while( isspace( *string )) string++;
- X if( *string && (comma = find_token( string, ',' ))) {
- X *comma = (char)0;
- X word = atoi( string );
- X /* else word not found */
- X return( do_word( mac, comma + 1, word ));
- X }
- X logprintf( argument_missing, "word", string );
- X return( 1 );
- X}
- X
- Xstatic int
- Xfn_words( struct macro *mac, char *string )
- X{
- X char buf[ 20 ];
- X sprintf( buf, "%d", count_args( string ));
- X mac->expansion = strdup( buf );
- X return( 0 );
- X}
- X
- Xstatic int
- Xfn_notimp( struct macro *mac, char *string )
- X{
- X logfile( "Function call not implemented\n" );
- X return( 1 );
- X}
- X
- X/*************************************************************************/
- X
- X/* sorted array for binary search */
- X#define MAX_FNCALL 21
- Xstatic struct fncall fncarray[ MAX_FNCALL ] = {
- X "addprefix", fn_addprefix,
- X "addsuffix", fn_addsuffix,
- X "basename", fn_basename,
- X "dir", fn_notimp,
- X "filter", fn_filter,
- X "filter-out", fn_filter_out,
- X "findstring", fn_findstring,
- X "firstword", fn_firstword,
- X "foreach", fn_notimp,
- X "join", fn_notimp,
- X "notdir", fn_notimp,
- X "origin", fn_notimp,
- X "patsubst", fn_notimp,
- X "shell", fn_notimp,
- X "sort", fn_notimp,
- X "strip", fn_strip,
- X "subst", fn_subst,
- X "suffix", fn_notimp,
- X "wildcard", fn_wildcard,
- X "word", fn_word,
- X "words", fn_words
- X};
- X
- X/* binary search to find the function */
- Xstruct fncall *
- Xfind_fncall( char *name )
- X{
- X register struct fncall *array = fncarray;
- X int first = 0L;
- X int last = MAX_FNCALL - 1;
- X int mid;
- X int diff;
- X
- X /* binary search */
- X while( first <= last ) {
- X mid = (first+last) / 2;
- X diff = strcmp( name, array[ mid ].name );
- X if( !diff )
- X return( &array[ mid ] ); /* found */
- X if( first == last ) break; /* not found */
- X if( diff < 0 ) last = mid - 1;
- X else first = mid + 1;
- X }
- X return( NULL ); /* not found */
- X}
- X
- X#else
- X
- X/* No FNCALLS */
- Xstruct fncall *
- Xfind_fncall( char *name )
- X{
- X return( NULL ); /* not found */
- X}
- X
- X#endif
- X
- END_OF_FILE
- if test 10300 -ne `wc -c <'fncall.c'`; then
- echo shar: \"'fncall.c'\" unpacked with wrong size!
- fi
- # end of 'fncall.c'
- fi
- if test -f 'input.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'input.c'\"
- else
- echo shar: Extracting \"'input.c'\" \(7586 characters\)
- sed "s/^X//" >'input.c' <<'END_OF_FILE'
- X/* input.c
- X * (c) Copyright 1991 by Ben Eng, All Rights Reserved
- X *
- X */
- X
- X#include <ctype.h>
- X#include <clib/exec_protos.h>
- X
- X#include "make.h"
- X#include "depend.h"
- X
- Xint line_number;
- X
- Xstatic struct List Mstack =
- X{
- X (struct Node *)&Mstack.lh_Tail, /* lh_Head */
- X (struct Node *)NULL, /* lh_Tail */
- X (struct Node *)&Mstack.lh_Head, /* lh_TailPred */
- X (UBYTE)NT_USER,
- X (UBYTE)0
- X};
- X
- X#define STATE_IF_T 1
- X#define STATE_IF_F 2 /* skip lines mode */
- X#define STATE_EL_T 3 /* skip lines mode */
- X#define STATE_EL_F 4
- X
- Xstatic struct mstate {
- X struct Node node;
- X int state;
- X};
- X
- Xstatic struct drctvs {
- X char *directive; /* the name of the directive */
- X int (*call)(char *); /* function call */
- X};
- X
- X/* binary search to find the function */
- Xstruct drctvs *
- Xfind_drctvs( struct drctvs *array, int array_size, char *name )
- X{
- X int first = 0L;
- X int last = array_size - 1;
- X int mid;
- X int diff, len;
- X
- X /* binary search */
- X while( first <= last ) {
- X mid = (first+last) / 2;
- X len = strlen( array[ mid ].directive );
- X diff = strncmp( name, array[ mid ].directive, len );
- X if( !diff ) return( &array[ mid ] ); /* found */
- X if( first == last ) break; /* not found */
- X if( diff < 0 ) last = mid - 1;
- X else first = mid + 1;
- X }
- X return( NULL ); /* not found */
- X}
- X
- Xstatic int
- Xpush_state( struct List *stack, long state )
- X{
- X struct mstate *new = (struct mstate *)malloc( sizeof(struct mstate));
- X if( !new ) return( 1 ); /* no memory */
- X new->node.ln_Type = NT_USER;
- X new->state = state;
- X AddHead( stack, &new->node );
- X return( 0 );
- X}
- X
- Xstatic int
- Xpop_state( struct List *stack )
- X{
- X struct mstate *new = (struct mstate *)RemHead( stack );
- X int state;
- X if( !new ) return( 0 ); /* no state */
- X state = new->state;
- X free( new );
- X return( state );
- X}
- X
- Xstatic void
- Xclear_stack( struct List *stack )
- X{
- X struct Node *node, *succ;
- X
- X for( node = stack->lh_Head; node->ln_Succ; node = succ ) {
- X succ = node->ln_Succ;
- X free( node );
- X }
- X NewList( stack );
- X}
- X
- X/* returns true if we are still within a conditional */
- Xint
- Xget_directive_state( void )
- X{
- X struct mstate *first = (struct mstate *)Mstack.lh_Head;
- X if( !first->node.ln_Succ ) return( 0 );
- X return( first->state );
- X}
- X
- X/* conditions return 0 for false, 1 for true, -1 for error */
- Xstatic int
- Xdo_condeq( char *string, int negate )
- X{
- X char *exp1 = NULL, *exp2 = NULL;
- X char *lparen = string, *comma, *rparen;
- X int retval = -1; /* default to error */
- X
- X exp1 = (char*)malloc( Param.MaxLine );
- X exp2 = (char*)malloc( Param.MaxLine );
- X if( !exp1 || !exp2 ) goto death;
- X
- X while( *lparen && *lparen != '(' ) lparen++;
- X if( *lparen != '(' ) goto death;
- X comma = lparen + 1;
- X while( *comma && *comma != ',' ) comma++;
- X if( *comma != ',' ) goto death;
- X rparen = comma + 1;
- X while( *rparen && *rparen != ')' ) rparen++;
- X if( *rparen != ')' ) goto death;
- X
- X *comma = *rparen = (char)0;
- X if( expand_macros( exp1, lparen + 1, Param.MaxLine ) ||
- X expand_macros( exp2, comma + 1, Param.MaxLine )) goto death;
- X
- X if( negate )
- X retval = strcmp( exp1, exp2 ) ? 1 : 0; /* set condition code */
- X else
- X retval = strcmp( exp1, exp2 ) ? 0 : 1; /* set condition code */
- X
- Xdeath:
- X if( exp1 ) free( exp1 );
- X if( exp2 ) free( exp2 );
- X return( retval );
- X}
- X
- Xstatic int
- Xdo_conddef( char *string, int negate )
- X{
- X char *lparen = string, *rparen;
- X char *exp1 = NULL;
- X int retval = -1; /* default to error */
- X
- X exp1 = (char *)malloc( Param.MaxLine );
- X if( !exp1 ) goto death;
- X
- X while( *lparen && *lparen != '(' ) lparen++;
- X if( *lparen != '(' ) goto death;
- X rparen = lparen + 1;
- X while( *rparen && *rparen != ')' ) rparen++;
- X if( *rparen != ')' ) goto death;
- X
- X *rparen = (char)0;
- X retval = find_macro( lparen + 1 ) ? 1 : 0;
- X if( negate ) retval = retval ? 0 : 1;
- Xdeath:
- X if( exp1 ) free( exp1 );
- X return( retval );
- X}
- X
- Xstatic int
- Xcdrctv_eq( char *string )
- X{
- X return( do_condeq( string, 0 ));
- X}
- Xstatic int
- Xcdrctv_neq( char *string )
- X{
- X return( do_condeq( string, 1 ));
- X}
- X
- Xstatic int
- Xcdrctv_def( char *string )
- X{
- X return( do_conddef( string, 0 ));
- X}
- Xstatic int
- Xcdrctv_ndef( char *string )
- X{
- X return( do_conddef( string, 1 ));
- X}
- X
- X/* keep it sorted for binary search */
- X#define MAX_CDRCTVS 4
- Xstatic struct drctvs carray[ MAX_CDRCTVS ] = {
- X { "def", cdrctv_def },
- X { "eq", cdrctv_eq },
- X { "ndef", cdrctv_ndef },
- X { "neq", cdrctv_neq }
- X};
- X
- Xstatic int
- Xdrctv_else( char *string )
- X{
- X int state = pop_state( &Mstack );
- X int newstate = 0;
- X
- X if( state != STATE_IF_T && state != STATE_IF_F ) {
- X logfile( "ERROR: else with no matching conditional\n" );
- X return( 1 );
- X }
- X newstate = (state == STATE_IF_T) ? STATE_EL_T : STATE_EL_F;
- X debugprintf( 4, ("else changes state from %d to %d\n",
- X state, newstate ));
- X push_state( &Mstack, newstate );
- X return( 0 );
- X}
- X
- Xstatic int
- Xdrctv_endif( char *string )
- X{
- X int state = pop_state( &Mstack );
- X
- X if( !state ) {
- X logfile( "ERROR: endif with no matching conditional\n" );
- X return( 1 );
- X }
- X return( 0 );
- X}
- X
- Xstatic int
- Xdrctv_if( char *string )
- X{
- X struct drctvs *cdrctv;
- X int condition;
- X
- X while( isspace( *string )) string++;
- X if( !*string ) {
- X logfile( "No condition given\n" );
- X return( 1 );
- X }
- X
- X if( cdrctv = find_drctvs( carray, MAX_CDRCTVS, string )) {
- X debugprintf( 4, ("condition %s\n", string ));
- X condition = (*cdrctv->call)( string + strlen( cdrctv->directive ));
- X debugprintf( 4, ("condition returns %d\n", condition ));
- X if( condition < 0 ) {
- X logprintf( "Error in condition: %s\n", string );
- X return( 1 );
- X }
- X else if( condition ) { /* execute the true code */
- X push_state( &Mstack, STATE_IF_T );
- X return( 0 );
- X }
- X else { /* execute the false code */
- X push_state( &Mstack, STATE_IF_F );
- X return( 0 );
- X }
- X }
- X logprintf( "Unrecognized condition: %s\n", string );
- X return( 1 );
- X}
- X
- Xstatic int
- Xdrctv_pragma( char *string )
- X{
- X int i, arguments, retval = 1;
- X char **argv = NULL;
- X
- X while( isspace( *string )) string++;
- X if( arguments = count_args( string ) + 1) {
- X if( argv = (char **)malloc( (arguments + 1) * sizeof(char *)) ) {
- X for( i = 1; i < arguments; i++ ) {
- X argv[ i ] = find_word( string, i );
- X }
- X argv[ 0 ] = version_string + 7;
- X argv[ arguments ] = NULL;
- X retval = parse_parameters( arguments, argv );
- X free( argv );
- X }
- X }
- X debugprintf( 3,( "Pragma(%d,%s)\n", arguments, string ));
- X return( retval );
- X}
- X
- X/* keep it sorted for binary search */
- X#define MAX_MDRCTVS 4
- Xstatic struct drctvs darray[ MAX_MDRCTVS ] = {
- X { "else", drctv_else },
- X { "endif", drctv_endif },
- X { "if", drctv_if },
- X { "pragma", drctv_pragma }
- X};
- X
- X/* get a non-comment line
- X */
- Xstatic int
- Xget_ncline( char *buf, int sz, FILE *in )
- X{
- X char *inbuf, *cptr;
- X int total, len;
- X
- X do {
- X if( feof( in )) return( 1 );
- X if( !fgets( buf, sz, in )) return( 1);
- X line_number++;
- X total = strlen( buf );
- X inbuf = buf;
- X while( cptr = strrchr( inbuf, '\\' ) ){
- X if( cptr[1] != '\n' ) break;
- X total -= 2; /* subtract backslash newline */
- X inbuf = cptr;
- X if( total >= sz ) break;
- X if( feof( in )) return( 1 );
- X if( !fgets( inbuf, sz - total, in )) return( 1 );
- X line_number++;
- X total += strlen( inbuf );
- X }
- X } while( *buf == '#' );
- X strip_trailspace( buf );
- X return( 0 );
- X}
- X
- X/* get the next valid line from a Makefile
- X */
- Xint
- Xgetline( char *buf, int sz, FILE *in )
- X{
- X struct drctvs *found = NULL;
- X int st, state = 0;
- X do {
- X if( state && !found )
- X debugprintf( 4, ("skipped[state=%d] %s\n", state, buf ));
- X st = get_ncline( buf, sz, in );
- X if( !st ) {
- X if( found = find_drctvs( darray, MAX_MDRCTVS, buf )) {
- X if( st = (*found->call)( buf + strlen( found->directive )))
- X clear_stack( &Mstack );
- X }
- X }
- X state = get_directive_state();
- X } while( !st && (state == STATE_IF_F || state == STATE_EL_T || found ));
- X
- X return( st );
- X}
- X
- END_OF_FILE
- if test 7586 -ne `wc -c <'input.c'`; then
- echo shar: \"'input.c'\" unpacked with wrong size!
- fi
- # end of 'input.c'
- fi
- if test -f 'make.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'make.c'\"
- else
- echo shar: Extracting \"'make.c'\" \(5200 characters\)
- sed "s/^X//" >'make.c' <<'END_OF_FILE'
- X/* make.c
- X * (c) Copyright 1991 by Ben Eng, All Rights Reserved
- X *
- X */
- X
- X#include <string.h>
- X#include <ctype.h>
- X#include <fcntl.h>
- X
- X#include <clib/exec_protos.h>
- X#include <clib/dos_protos.h>
- X
- X#include "make.h"
- X#include "depend.h"
- X
- Xstatic int make_implicit( char *goalname, int *remake_flag );
- X
- X/*
- X * Get the modification time of a file. If the first
- X * doesn't exist, it's modtime is set to 0.
- X */
- X
- Xtime_t
- Xmodtime( char *filename )
- X{
- X struct FileInfoBlock *fib;
- X BPTR myLock;
- X long ioErr;
- X time_t mtime = 0L;
- X
- X fib = (struct FileInfoBlock *)malloc( sizeof(struct FileInfoBlock));
- X if( fib ) {
- X if( !(myLock = Lock( filename, ACCESS_READ ))) {
- X if( (ioErr = IoErr()) != ERROR_OBJECT_NOT_FOUND)
- X logprintf( "Can't Lock '%s'; error %ld\n", filename, ioErr );
- X }
- X else if( !Examine( myLock, fib )) {
- X UnLock(myLock);
- X logprintf( "Can't Examine '%s'; error %ld", filename, IoErr() );
- X }
- X else {
- X mtime = fib->fib_Date.ds_Tick / TICKS_PER_SECOND +
- X 60*fib->fib_Date.ds_Minute + 86400 * fib->fib_Date.ds_Days;
- X UnLock( myLock );
- X }
- X free( fib );
- X }
- X return( mtime );
- X}
- X
- X/* return true if targ1 is newer than targ2 */
- Xint
- Xisnewer( char *targ1, char *targ2 )
- X{
- X time_t t1, t2;
- X long diff;
- X int retval;
- X
- X t1 = modtime( targ1 );
- X t2 = modtime( targ2 );
- X diff = (long)(t1 - t2);
- X retval = (diff > 0L) ? 1 : 0;
- X
- X debugprintf( 5, ("isnewer %s=%ld,%s=%ld diff=%ld: %s\n", targ1, t1,
- X targ2, t2, diff, (retval) ? "yes" : "no" ));
- X
- X return( retval );
- X}
- X
- X/* recursively make a target filename */
- Xint
- Xmake_filename( const char *goalname, int *made )
- X{
- X int remake_flag = (Param.all_mode) ? 1 : 0;
- X struct depend *dep;
- X struct List *cmdlist;
- X struct target *goal = find_target( goalname );
- X char *depname = NULL;
- X
- X Global.recursion_level++;
- X *made = 0;
- X
- X if( Global.recursion_level == 1 ) {
- X logprintf( "\tmake( %s )\n", goalname );
- X }
- X else {
- X debugprintf( 1, ( "\n\tmake %d ( %s )\n", Global.recursion_level,
- X goalname ));
- X }
- X if( goal ) {
- X if( goal->dependlist.lh_Head->ln_Succ ) {
- X for( dep = (struct depend *)goal->dependlist.lh_Head;
- X dep->node.ln_Succ; dep = dep->node.ln_Succ ) {
- X int made_flag;
- X
- X debugprintf( 1, ("%s depends on %s\n", goalname, dep->name ));
- X if( make_filename( dep->name, &made_flag )) return( 1 );
- X if( made_flag || isnewer( dep->name, goalname )) {
- X depname = dep->name;
- X remake_flag = 1;
- X }
- X } /* for */
- X } /* if has dependencies */
- X else remake_flag = 1;
- X } /* if */
- X
- X /* if no explicit rule for goal OR goal has no commands */
- X if( !goal || !goal->commandlist.lh_Head->ln_Succ ) {
- X int retval = make_implicit( goalname, &remake_flag );
- X --Global.recursion_level;
- X *made = remake_flag;
- X return( retval ); /* illegal reuse of remake_flag :-) */
- X }
- X
- X --Global.recursion_level;
- X
- X if( remake_flag ) {
- X struct List *cmdlist;
- X int retval;
- X
- X cmdlist = (goal->flags & TF_OWNER ) ? &goal->commandlist :
- X goal->alternate;
- X if( cmdlist->lh_Head->ln_Succ ) {
- X set_target_macros( goalname, depname );
- X retval = recipe( goalname, cmdlist );
- X set_target_macros( NULL, NULL );
- X if( retval ) return( 1 );
- X *made = 1;
- X }
- X }
- X else {
- X debugprintf( 2,("%s is up to date\n", goal->name ));
- X }
- X return( 0 );
- X}
- X
- X/* use this inference engine as a last resort
- X * use suffix rules to determine dependencies and commands for goalname
- X */
- Xstatic int
- Xmake_implicit( char *goalname, int *remake_flag )
- X{
- X char *depfile = (char *)malloc( MAXPATHNAME );
- X char *depname = NULL;
- X struct suffixrule *sr;
- X char *dot;
- X char suf[ MAXSUFFIX ];
- X
- X debugprintf( 1, ("\tmake_implicit( %s )\n", goalname ));
- X
- X if( !depfile ) goto death; /* no mem */
- X
- X dot = strrchr( goalname, '.' );
- X if( !dot ) goto out;
- X
- X strcpy( suf, dot + 1 );
- X for( sr = &Global.suffixlist.lh_Head; sr->node.ln_Succ;
- X sr = sr->node.ln_Succ ) {
- X if( !strcmp( suf, sr->tar_suf ) ) {
- X debugprintf( 2, ("Matched Suffix rule .%s.%s to %s\n",
- X sr->dep_suf, sr->tar_suf, goalname ));
- X if( *sr->dep_suf ) {
- X strcpy( depfile, goalname );
- X dot = strrchr( depfile, '.' );
- X strcpy( dot + 1, sr->dep_suf );
- X if( !access( depfile, 0 )) { /* found it */
- X int made_flag;
- X depname = depfile;
- X debugprintf( 2, ("double suffix rule matches %s\n",
- X depname ));
- X if( make_filename( depname, &made_flag )) {
- X goto death;
- X }
- X if( made_flag || isnewer( depname, goalname ))
- X *remake_flag = 1;
- X break;
- X } /* else not the right rule, continue to find another */
- X }
- X else {
- X debugprintf( 2, ("single suffix rule applies\n" ));
- X *remake_flag = 1;
- X break;
- X }
- X } /* if */
- X } /* for each suffix rule */
- X
- X if( !sr->node.ln_Succ ) {
- X logprintf( "don't know how to make %s\n", goalname );
- X goto death;
- X }
- X if( *remake_flag ) {
- X struct List *cmdlist;
- X struct target *goal = sr->targ;
- X
- X set_target_macros( goalname, depname );
- X
- X cmdlist = (goal->flags & TF_OWNER ) ? &goal->commandlist :
- X goal->alternate;
- X if( cmdlist->lh_Head->ln_Succ ) {
- X if( recipe( goalname, cmdlist )) goto death;
- X }
- X else *remake_flag = 0;
- X set_target_macros( NULL, NULL );
- X }
- X else {
- X debugprintf( 2,("%s is up to date\n", goalname ));
- X }
- Xout:
- X free( depfile );
- X return( 0 );
- Xdeath:
- X if( depfile ) free( depfile );
- X return( 1 );
- X}
- END_OF_FILE
- if test 5200 -ne `wc -c <'make.c'`; then
- echo shar: \"'make.c'\" unpacked with wrong size!
- fi
- # end of 'make.c'
- fi
- if test -f 'read.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'read.c'\"
- else
- echo shar: Extracting \"'read.c'\" \(8514 characters\)
- sed "s/^X//" >'read.c' <<'END_OF_FILE'
- X/* input.c
- X * (c) Copyright 1991 by Ben Eng, All Rights Reserved
- X *
- X */
- X
- X#include <ctype.h>
- X#include <clib/exec_protos.h>
- X
- X#include "make.h"
- X#include "depend.h"
- X
- Xextern int line_number;
- X
- X/* process a line that looks like
- X * target names: dependencies
- X */
- Xstruct target *
- Xprocess_targetline( char *line, struct List *cmdlist, int builtin_flag )
- X{
- X struct target *first_targ = NULL;
- X struct target *targ = NULL;
- X struct List *ownerlist = NULL;
- X char *delim, *nexttar;
- X char name[ 80 ];
- X char *expandlhs = NULL, *expandrhs = NULL;
- X long len;
- X
- X if( !(expandlhs = (char *)malloc( Param.MaxLine )) ||
- X !(expandrhs = (char *)malloc( Param.MaxLine ))) goto death;
- X
- X while( isspace( *line )) line++;
- X delim = find_token( line + 1, ':' );
- X if( !delim ) goto death;
- X len = (long)(delim - line);
- X if( !len ) goto death;
- X
- X memset( name, 0, sizeof( name ));
- X strncpy( name, line, delim - line );
- X
- X /* expand macros in targetnames */
- X if( expand_macros( expandlhs, name, Param.MaxLine )) goto death;
- X nexttar = expandlhs;
- X
- X if( !strcmp( ".SUFFIXES", expandlhs )) {
- X char suf[ MAXSUFFIX ];
- X
- X nexttar = delim + 1;
- X while( isspace( *nexttar )) nexttar++;
- X
- X /* expand macros in rhs */
- X if( *nexttar && expand_macros( expandrhs, nexttar, Param.MaxLine ))
- X goto death;
- X nexttar = expandrhs;
- X
- X for( ; ; ) {
- X while( isspace( *nexttar )) nexttar++;
- X if( *nexttar != '.' ) {
- X if( *nexttar ) {
- X printf( "bad suffix rule [%s] on line %d\n%s\n",
- X nexttar, line_number, line );
- X }
- X break;
- X }
- X nexttar = parse_strtok( suf, ++nexttar, sizeof(suf)-1, isnotsuf );
- X if( !*suf ) break;
- X first_targ = add_suffix_targets( suf );
- X }
- X targ = NULL;
- X goto death;
- X }
- X
- X /* for each target name left of the colon */
- X for(;;) {
- X struct depend *dep = NULL;
- X struct command *cmd = NULL;
- X char *next;
- X
- X nexttar = parse_str( name, nexttar, sizeof( name ));
- X if( !*name ) break; /* no more names */
- X
- X targ = find_target( name );
- X if( !targ ) {
- X targ = new_target( name );
- X if( !targ ) goto death;
- X targ->line_number = line_number;
- X }
- X if( builtin_flag ) targ->flags |= TF_BUILTIN;
- X
- X debugprintf( 5, ( "new target: %s\n", targ->name ) );
- X
- X if( !first_targ ) {
- X first_targ = targ;
- X first_targ->flags |= TF_OWNER;
- X ownerlist = &targ->commandlist;
- X }
- X
- X set_target_macros( name, NULL );
- X
- X /* find the dependencies */
- X next = delim + 1;
- X while( isspace( *next )) next++;
- X
- X /* expand macros in dependencies */
- X if( expand_macros( expandrhs, next, Param.MaxLine )) goto death;
- X next = expandrhs;
- X
- X /* for each dependency add to list */
- X for( ;; ) {
- X next = parse_str( name, next, sizeof( name ));
- X if( !*name ) break; /* no more names */
- X /* first check if that dependency already exists */
- X for( dep = targ->dependlist.lh_Head; dep->node.ln_Succ;
- X dep = dep->node.ln_Succ ) {
- X if( !strcmp( dep->name, name )) break;
- X }
- X
- X if( !dep->node.ln_Succ ) { /* doesn't exist already */
- X if( dep = new_depend( name ))
- X AddTail( &targ->dependlist, &dep->node );
- X else goto death;
- X }
- X else {
- X logprintf( "duplicate dependency %s for target %s\n",
- X name, targ->name );
- X }
- X }
- X /* for each command add to list */
- X if( targ->flags & TF_OWNER ) {
- X delete_commandlist( &targ->commandlist );
- X attach_list( &targ->commandlist, cmdlist );
- X }
- X else targ->alternate = ownerlist;
- X
- X if( !(targ->flags & TF_ADDED )) {
- X targ->flags |= TF_ADDED;
- X AddTail( &Global.targetlist, &targ->node );
- X }
- X targ = NULL;
- X } /* for */
- X set_target_macros( NULL, NULL ); /* delete $@ $* and $< */
- X
- Xdeath:
- X if( targ ) free( targ );
- X if( expandrhs ) free( expandrhs );
- X if( expandlhs ) free( expandlhs );
- X return( first_targ );
- X}
- X
- X/* process a line that looks like
- X * variable = value
- X */
- Xstruct macro *
- Xprocess_macroline( char *line )
- X{
- X struct macro *mac = NULL;
- X char *delim, *next;
- X char macroname[ MAX_MACRONAME ], *rhs;
- X char *expansion = NULL; /* dynamic */
- X long namelen, explen;
- X int do_expansion = 0;
- X int do_addition = 0;
- X
- X debugprintf( 5, ( "macroline %d: %s\n", line_number, line ) );
- X
- X while( isspace( *line )) line++; /* skip whitespace */
- X
- X delim = strchr( line, '=' ); /* cannot be escaped by backslash */
- X if( !delim ) goto death;
- X rhs = delim + 1;
- X
- X namelen = min( (long)(delim - line), sizeof(macroname)-1);
- X if( !namelen ) goto death;
- X
- X switch( *(delim-1)) {
- X case ':':
- X do_expansion = 1;
- X delim--;
- X namelen--;
- X break;
- X case '+':
- X do_addition = 1;
- X delim--;
- X namelen--;
- X break;
- X }
- X
- X next = line;
- X while( isspace( *next )) next++;
- X memset( macroname, 0, sizeof( macroname ));
- X for( int i = 0; next < delim && i < 79; i++ ) {
- X if( isspace( *next )) break;
- X macroname[ i ] = *next++;
- X }
- X
- X while( isspace( *rhs )) rhs++; /* skip whitespace */
- X
- X if( do_expansion && *rhs ) {
- X expansion = (char *)malloc( Param.MaxLine );
- X if( !expansion ) goto death;
- X if( expand_macros( expansion, rhs, Param.MaxLine )) goto death;
- X /* expand rhs */
- X rhs = expansion;
- X }
- X
- X if( mac = find_macro( macroname )) {
- X char *old = mac->expansion;
- X
- X if( do_addition && old ) {
- X if( mac->expansion = malloc(strlen( old ) + strlen( rhs ) + 1)) {
- X strcpy( mac->expansion, old );
- X strcat( mac->expansion, " " );
- X strcat( mac->expansion, rhs );
- X }
- X }
- X else mac->expansion = strdup( rhs );
- X if( old ) free( old );
- X }
- X else mac = new_macro( macroname, rhs );
- X
- X if( mac ) {
- X if( do_expansion ) mac->flags |= MF_SIMPLE;
- X if( !(mac->flags & MF_ADDED )) {
- X mac->flags |= MF_ADDED;
- X AddTail( &Global.macrolist, &mac->node );
- X }
- X debugprintf( 5, ( "assigned macro [%s] = [%s]\n",
- X mac->name, mac->expansion ));
- X }
- X else {
- X debugprintf( 2, ("error assigning macro [%s]\n", macroname ) );
- X }
- X
- X if( expansion ) free( expansion );
- X return( mac );
- Xdeath:
- X if( expansion ) free( expansion );
- X if( mac ) free( mac );
- X return( NULL );
- X}
- X
- X/* read in all rules and variables from this makefile
- X*/
- Xint
- Xinput_makefile( const char *makefile, int builtin_flag )
- X{
- X char *curline = NULL;
- X char *commandline = NULL;
- X FILE *infile = NULL;
- X int targetcount = 0, macrocount = 0;
- X int st;
- X
- X curline = (char *)malloc( Param.MaxLine );
- X commandline = (char *)malloc( Param.MaxLine );
- X if( !curline || !commandline ) goto death;
- X
- X infile = fopen( makefile, "r" );
- X if( !infile ) {
- X logprintf( "Cannot open %s\n", makefile );
- X goto death;
- X }
- X
- X debugprintf( 3,( "input Makefile: %s\n", makefile ));
- X
- X line_number = 0;
- X if( st = getline( curline, Param.MaxLine, infile )) goto death;
- X while( !st ) {
- X /* debugprintf( 5,( "getline %d: %s\n", line_number, curline )); */
- X if( strchr( curline, '=' )) {
- X macrocount++;
- X process_macroline( curline );
- X
- X st = getline( curline, Param.MaxLine, infile );
- X }
- X else if( isemptyline( curline )) {
- X st = getline( curline, Param.MaxLine, infile );
- X }
- X else {
- X struct List cmdList;
- X struct target *targ = NULL;
- X struct command *cmd = NULL;
- X char *delim;
- X
- X NewList( &cmdList );
- X
- X targetcount++;
- X *commandline = (char)0;
- X
- X delim = find_token( curline + 1, ':' );
- X if( delim ) {
- X if( delim = find_token( delim + 1, ';' ) ) {
- X *delim++ = (char)0;
- X *commandline = '\t'; /* commandlines begin with a tab */
- X strcpy( commandline + 1, delim );
- X }
- X }
- X
- X if( st = ( *commandline ) ? 0 :
- X getline( commandline, Param.MaxLine, infile )) break;
- X while( !st ) {
- X if( *commandline != '\t' ) break;
- X debugprintf( 5,("tabline %d: %s\n",line_number, commandline));
- X delim = commandline;
- X while( isspace( *delim )) delim++;
- X if( *delim ) { /* line is not empty */
- X if( cmd = new_command( delim ))
- X AddTail( &cmdList, &cmd->node );
- X else {
- X printf( "Could not add command for target\n" );
- X goto death;
- X }
- X }
- X st = getline( commandline, Param.MaxLine, infile );
- X } /* while */
- X
- X debugprintf( 4, ("targetline %d is %s\n", line_number, curline));
- X targ = process_targetline( curline, &cmdList, builtin_flag );
- X if( !targ ) {
- X logprintf( "Error in Makefile before line %d: %s\n",
- X line_number, curline );
- X goto death;
- X }
- X
- X strcpy( curline, commandline );
- X } /* else */
- X } /* while */
- X
- X debugprintf( 2,( "targetcount = %d\nmacrocount = %d\n", targetcount,
- X macrocount ));
- X
- X if( Param.debug && Param.verbosity >= 5 ) {
- X dump_all();
- X }
- X
- X if( get_directive_state()) {
- X logfile( "Missing endif directive in conditional\n" );
- X goto death;
- X }
- X
- X free( commandline );
- X free( curline );
- X fclose( infile );
- X return( 0 );
- Xdeath:
- X if( commandline ) free( commandline );
- X if( curline ) free( curline );
- X if( infile ) fclose( infile );
- X return( 1 );
- X}
- END_OF_FILE
- if test 8514 -ne `wc -c <'read.c'`; then
- echo shar: \"'read.c'\" unpacked with wrong size!
- fi
- # end of 'read.c'
- fi
- echo shar: End of archive 2 \(of 3\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
- Mail comments to the moderator at <amiga-request@uunet.uu.net>.
- Post requests for sources, and general discussion to comp.sys.amiga.misc.
-